﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace Jaiden.Data.Exporting
{
    public class CsvExportTarget : IExportTarget
    {
        private readonly Stream _stream;

        public CsvExportTarget(Stream stream)
        {
            _stream = stream;
        }

        public CsvExportTarget(string path) : this(File.Open(path, FileMode.Create))
        {
        }

        public Encoding Encoding { get; set; } = Encoding.UTF8;

        public void Export<T>(IEnumerable<T> data, IExportRole<T> role)
        {
            using (var sw = new StreamWriter(_stream, Encoding))
            {
                for (var i = 0; i < role.Columns.Count; i++)
                {
                    if (i > 0) sw.Write(',');
                    WriteField(sw, role.Columns[i].Name);
                }

                sw.WriteLine();
                foreach (var item in data)
                {
                    for (var i = 0; i < role.Columns.Count; i++)
                    {
                        if (i > 0) sw.Write(',');
                        WriteField(sw, role.Columns[i].ValueGetter(item));
                    }

                    sw.WriteLine();
                }
            }
        }

        protected void WriteField(StreamWriter writer, object field)
        {
            if (field == null) return;
            if (field is string)
            {
                var str = field as string;
                var wapper = false;
                if (str.IndexOf('\"') != -1)
                {
                    str = str.Replace("\"", "\"\"");
                    wapper = true;
                }

                if (str.IndexOf(',') != -1) wapper = true;
                if (str.IndexOf('\n') != -1) wapper = true;
                if (wapper)
                {
                    writer.Write('\"');
                    writer.Write(str);
                    writer.Write('\"');
                }
                else
                {
                    writer.Write(str);
                }
            }
            else
            {
                WriteField(writer, Convert.ToString(field));
            }
        }
    }
}